home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / osrc.arc / NRCMD.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-28  |  13.4 KB  |  612 lines

  1. /* net/rom user command processing
  2.  * Dan Frank, W9NK
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include "global.h"
  7. #include "mbuf.h"
  8. #include "ax25.h"
  9. #include "netrom.h"
  10. #include "timer.h"
  11. #include "iface.h"
  12. #include "lapb.h"
  13. #include "cmdparse.h"
  14. #include <ctype.h>
  15.  
  16. extern struct iface *Ifaces ;
  17. static int donfdump(),doobsotick(),donodetick(),
  18.     dointerface(), dobcnodes(), donodetimer(), donrroute(),
  19.     doobsotimer(), donodefilter(), donrverbose() ;
  20.  
  21. static struct cmds Nrcmds[] = {
  22.     "bcnodes",    dobcnodes,    0, 2,    "netrom bcnodes <interface>",
  23.     "interface",    dointerface,    0, 4,
  24.         "netrom interface <interface> <alias> <quality>",
  25.     "nodefilter",    donodefilter,    0, 0,    NULLCHAR,
  26.     "nodetimer",    donodetimer,    0, 0,    NULLCHAR,
  27.     "obsotimer",    doobsotimer,    0, 0,    NULLCHAR,
  28.     "route",    donrroute,    0, 0,    NULLCHAR,
  29.     "verbose",    donrverbose,0, 0,    NULLCHAR,
  30.     NULLCHAR,    NULLFP,        0, 0,
  31.         "netrom subcommands: bcnodes interface nodetimer nodefilter obsotimer route verbose",
  32. } ;
  33.  
  34. static struct timer Nodetimer ;    /* timer for nodes broadcasts */
  35. static struct timer Obsotimer ;    /* timer for aging routes */
  36.  
  37. /* Command multiplexer */
  38. donetrom(argc,argv,envp)
  39. int argc ;
  40. char *argv[] ;
  41. void *envp;
  42. {
  43.     return subcmd(Nrcmds,argc,argv,envp) ;
  44. }
  45.  
  46. static int dorouteadd(), doroutedrop(), doroutedump(), dorouteinfo() ;
  47.  
  48. static struct cmds Routecmds[] = {
  49.     "add",    dorouteadd,    0, 6,
  50.         "netrom route add <alias> <destination> <interface> <quality> <neighbor>",
  51.     "drop",    doroutedrop, 0, 4,
  52.         "netrom route drop <destination> <neighbor> <interface>",
  53.     "info", dorouteinfo, 0, 2,
  54.         "netrom route info <destination>",
  55.     NULLCHAR,    NULLFP,    0, 0,
  56.         "netrom route subcommands: add drop info",
  57. } ;
  58.  
  59. /* Route command multiplexer */
  60. static
  61. donrroute(argc, argv,envp)
  62. int argc ;
  63. char *argv[] ;
  64. void *envp;
  65. {
  66.     if (argc < 2) {
  67.         doroutedump() ;
  68.         return 0 ;
  69.     }
  70.     return subcmd(Routecmds,argc,argv,envp) ;
  71. }
  72.  
  73. /* Dump a list of known routes */
  74. static
  75. doroutedump()
  76. {
  77.     register struct nrroute_tab *rp ;
  78.     register int i, column ;
  79.     char buf[16] ;
  80.     char *cp ;
  81.     
  82.     column = 1 ;
  83.     
  84.     for (i = 0 ; i < NRNUMCHAINS ; i++)
  85.         for (rp = Nrroute_tab[i] ; rp != NULLNRRTAB ; rp = rp->next) {
  86.             strcpy(buf,rp->alias) ;
  87.             /* remove trailing spaces */
  88.             if ((cp = strchr(buf,' ')) == NULLCHAR)
  89.                 cp = &buf[strlen(buf)] ;
  90.             if (cp != buf)        /* don't include colon for null alias */
  91.                 *cp++ = ':' ;
  92.             pax25(cp,&rp->call) ;
  93.             printf("%-16s  ",buf) ;
  94.             if (column++ == 4) {
  95.                 printf("\n") ;
  96.                 column = 1 ;
  97.             }
  98.         }
  99.  
  100.     if (column != 1)
  101.         printf("\n") ;
  102.         
  103.     return 0 ;
  104. }
  105.  
  106. /* print detailed information on an individual route */
  107. static int
  108. dorouteinfo(argc,argv)
  109. int argc ;
  110. char *argv[] ;
  111. {
  112.     register struct nrroute_tab *rp ;
  113.     register struct nr_bind *bp ;
  114.     register struct nrnbr_tab *np ;
  115.     struct ax25_addr dest ;
  116.     char neighbor[60] ;
  117.  
  118.     if (setcall(&dest,argv[1]) == -1) {
  119.         printf ("bad destination name\n") ;
  120.         return -1 ;
  121.     }
  122.         
  123.     if ((rp = find_nrroute(&dest)) == NULLNRRTAB) {
  124.         printf("no such route\n") ;
  125.         return -1 ;
  126.     }
  127.  
  128.     for (bp = rp->routes ; bp != NULLNRBIND ; bp = bp->next) {
  129.         np = bp->via ;
  130.         psax25(neighbor,np->call) ;
  131.         printf("%1s %3d  %3d  %-8s  %s\n",
  132.                 (bp->flags & NRB_PERMANENT ? "P" :
  133.                  bp->flags & NRB_RECORDED ? "R" : " "),
  134.                 bp->quality,bp->obsocnt,
  135.                 Nrifaces[np->iface].iface->name,
  136.                 neighbor) ;
  137.     }
  138.     return 0 ;
  139. }
  140.         
  141. /* convert a null-terminated alias name to a blank-filled, upcased */
  142. /* version.  Return -1 on failure. */
  143. static int
  144. putalias(to,from)
  145. register char *to, *from ;
  146. {
  147.     int len, i ;
  148.     
  149.     if ((len = strlen(from)) > ALEN) {
  150.         printf ("alias too long - six characters max\n") ;
  151.         return -1 ;
  152.     }
  153.     
  154.     for (i = 0 ; i < ALEN ; i++) {
  155.         if (i < len) {
  156.             if (islower(*from))
  157.                 *to++ = toupper(*from++) ;
  158.             else
  159.                 *to++ = *from++ ;
  160.         }
  161.         else
  162.             *to++ = ' ' ;
  163.     }
  164.             
  165.     *to = '\0' ;
  166.     return 0 ;
  167. }
  168.  
  169. /* Add a route */
  170. static int
  171. dorouteadd(argc, argv)
  172. int argc ;
  173. char *argv[] ;
  174. {
  175.     char alias[7] ;
  176.     struct ax25_addr dest ;
  177.     unsigned quality ;
  178.     char neighbor[AXALEN * 3] ;
  179.     register int i ;
  180.     int naddr ;
  181.  
  182.     /* format alias (putalias prints error message if necessary) */
  183.     if (putalias(alias,argv[1]) == -1)
  184.         return -1 ;
  185.  
  186.     /* format destination callsign */
  187.     if (setcall(&dest,argv[2]) == -1) {
  188.         printf("bad destination callsign\n") ;
  189.         return -1 ;
  190.     }
  191.  
  192.     /* find interface */
  193.     for (i = 0 ; i < Nr_numiface ; i++)
  194.         if (!strcmp(Nrifaces[i].iface->name,argv[3]))
  195.             break ;
  196.     if (i == Nr_numiface) {
  197.         printf("Interface \"%s\" not found\n",argv[3]) ;
  198.         return -1 ;
  199.     }
  200.     
  201.     /* get and check quality value */
  202.     if ((quality = atoi(argv[4])) > 255) {
  203.         printf("maximum route quality is 255\n") ;
  204.         return -1 ;
  205.     }
  206.  
  207.     /* Change from 871225 -- no digis in net/rom table */
  208.     naddr = argc - 5 ;
  209.     if (naddr > 1) {
  210.         printf("Use the ax25 route command to specify digipeaters\n") ;
  211.         return -1 ;
  212.     }
  213.     
  214.     /* format neighbor address string */
  215.     setpath(neighbor,&argv[5],naddr) ;
  216.  
  217.     return nr_routeadd(alias,&dest,i,quality,neighbor,1,0) ;
  218. }
  219.  
  220.  
  221. /* drop a route */
  222. static int
  223. doroutedrop(argc,argv)
  224. int argc ;
  225. char *argv[] ;
  226. {
  227.     struct ax25_addr dest, neighbor ;
  228.     register int i ;
  229.  
  230.     /* format destination and neighbor callsigns */
  231.     if (setcall(&dest,argv[1]) == -1) {
  232.         printf("bad destination callsign\n") ;
  233.         return -1 ;
  234.     }
  235.     if (setcall(&neighbor,argv[2]) == -1) {
  236.         printf("bad neighbor callsign\n") ;
  237.         return -1 ;
  238.     }
  239.  
  240.     /* find interface */
  241.     for (i = 0 ; i < Nr_numiface ; i++)
  242.         if (!strcmp(Nrifaces[i].iface->name,argv[3]))
  243.             break ;
  244.     if (i == Nr_numiface) {
  245.         printf("Interface \"%s\" not found\n",argv[3]) ;
  246.         return -1 ;
  247.     }
  248.  
  249.     return nr_routedrop(&dest,&neighbor,i) ;
  250. }
  251.     
  252.     
  253. /* make an interface available to net/rom */
  254. static int
  255. dointerface(argc,argv)
  256. int argc ;
  257. char *argv[] ;
  258. {
  259.     int i;
  260.     register struct iface *ifp ;
  261.  
  262.     if (Nr_iface == NULLIF) {
  263.         printf("Attach netrom interface first\n") ;
  264.         return 1 ;
  265.     }
  266.     
  267.     if (Nr_numiface >= NRNUMIFACE) {
  268.         printf("Only %d net/rom interfaces available\n",NRNUMIFACE) ;
  269.         return 1 ;
  270.     }
  271.     
  272.     for(ifp=Ifaces;ifp != NULLIF;ifp = ifp->next){
  273.         if(strcmp(argv[1],ifp->name) == 0)
  274.             break;
  275.     }
  276.     if(ifp == NULLIF){
  277.         printf("Interface \"%s\" unknown\n",argv[1]);
  278.         return 1;
  279.     }
  280.     for (i = 0 ; i < Nr_numiface ; i++)
  281.         if (Nrifaces[i].iface == ifp) {
  282.             printf("Interface \"%s\" is already registered\n",argv[1]) ;
  283.             return 1 ;
  284.         }
  285.         
  286.     Nrifaces[Nr_numiface].iface = ifp ;
  287.  
  288.     if (putalias(Nrifaces[Nr_numiface].alias,argv[2]) == -1)
  289.         return 1 ;
  290.         
  291.     if ((Nrifaces[Nr_numiface].quality = atoi(argv[3])) > 255) {
  292.         printf("Quality cannot be greater than 255\n") ;
  293.         return 1 ;
  294.     }
  295.         
  296.     Nr_numiface++ ;            /* accept this interface */
  297.     return 0 ;
  298. }
  299.  
  300. /* Broadcast nodes list on named interface. */
  301. static int
  302. dobcnodes(argc,argv)
  303. int argc ;
  304. char *argv[] ;
  305. {
  306.     register int i ;
  307.  
  308.     for (i = 0 ; i < Nr_numiface ; i++)
  309.         if (!strcmp(Nrifaces[i].iface->name,argv[1]))
  310.             break ;
  311.     if (i == Nr_numiface) {
  312.         printf("Interface \"%s\" not found\n",argv[1]) ;
  313.         return 1 ;
  314.     }
  315.         
  316.     nr_bcnodes(i) ;
  317. }
  318.  
  319. #define TICKSPERSEC    (1000L / MSPTICK)    /* Ticks per second */
  320.  
  321. /* Set outbound node broadcast interval */
  322. static int
  323. donodetimer(argc,argv)
  324. int argc;
  325. char *argv[];
  326. {
  327.     if(argc < 2){
  328.         printf("%lu/%lu\n",(Nodetimer.start - Nodetimer.count)/TICKSPERSEC,
  329.         Nodetimer.start/TICKSPERSEC);
  330.         return 0;
  331.     }
  332.     stop_timer(&Nodetimer) ;    /* in case it's already running */
  333.     Nodetimer.func = (void (*)())donodetick;/* what to call on timeout */
  334.     Nodetimer.arg = NULLCHAR;        /* dummy value */
  335.     Nodetimer.start = atoi(argv[1])*TICKSPERSEC;    /* set timer duration */
  336.     start_timer(&Nodetimer);        /* and fire it up */
  337.     return 0;
  338. }
  339.  
  340. static int
  341. donodetick()
  342. {
  343.     register int i ;
  344.  
  345.     for (i = 0 ; i < Nr_numiface ; i++)
  346.         nr_bcnodes(i) ;
  347.  
  348.     /* Restart timer */
  349.     start_timer(&Nodetimer) ;
  350. }
  351.  
  352. /* Set timer for aging routes */
  353. static int
  354. doobsotimer(argc,argv)
  355. int argc;
  356. char *argv[];
  357. {
  358.     if(argc < 2){
  359.         printf("%lu/%lu\n",(Obsotimer.start - Obsotimer.count)/TICKSPERSEC,
  360.         Obsotimer.start/TICKSPERSEC);
  361.         return 0;
  362.     }
  363.     stop_timer(&Obsotimer) ;    /* just in case it's already running */
  364.     Obsotimer.func = (void (*)())doobsotick;/* what to call on timeout */
  365.     Obsotimer.arg = NULLCHAR;        /* dummy value */
  366.     Obsotimer.start = atoi(argv[1])*TICKSPERSEC;    /* set timer duration */
  367.     start_timer(&Obsotimer);        /* and fire it up */
  368.     return 0;
  369. }
  370.  
  371.  
  372. /* Go through the routing table, reducing the obsolescence count of
  373.  * non-permanent routes, and purging them if the count reaches 0
  374.  */
  375. static int
  376. doobsotick()
  377. {
  378.     register struct nrnbr_tab *np ;
  379.     register struct nrroute_tab *rp, *rpnext ;
  380.     register struct nr_bind *bp, *bpnext ;
  381.     struct ax25_addr neighbor ;
  382.     int i ;
  383.  
  384.     for (i = 0 ; i < NRNUMCHAINS ; i++) {
  385.         for (rp = Nrroute_tab[i] ; rp != NULLNRRTAB ; rp = rpnext) {
  386.             rpnext = rp->next ;     /* save in case we free this route */
  387.             for (bp = rp->routes ; bp != NULLNRBIND ; bp = bpnext) {
  388.                 bpnext = bp->next ;    /* in case we free this binding */
  389.                 if (bp->flags & NRB_PERMANENT)    /* don't age these */
  390.                     continue ;
  391.                 if (--bp->obsocnt == 0) {        /* time's up! */
  392.                     if (bp->next != NULLNRBIND)
  393.                         bp->next->prev = bp->prev ;
  394.                     if (bp->prev != NULLNRBIND)
  395.                         bp->prev->next = bp->next ;
  396.                     else
  397.                         rp->routes = bp->next ;
  398.                     rp->num_routes-- ;            /* one less binding */
  399.                     np = bp->via ;                /* find the neighbor */
  400.                     free(bp) ;                    /* now we can free the bind */
  401.                     /* Check to see if we can free the neighbor */
  402.                     if (--np->refcnt == 0) {
  403.                         if (np->next != NULLNTAB)
  404.                             np->next->prev = np->prev ;
  405.                         if (np->prev != NULLNTAB)
  406.                             np->prev->next = np->next ;
  407.                         else {
  408.                             memcpy(neighbor.call,np->call,ALEN) ;
  409.                             neighbor.ssid = np->call[ALEN] ;
  410.                             Nrnbr_tab[nrhash(&neighbor)] = np->next ;
  411.                         }
  412.                         free(np) ;    /* free the storage */
  413.                     }
  414.                 }
  415.             }
  416.             if (rp->num_routes == 0) {        /* did we free them all? */
  417.                 if (rp->next != NULLNRRTAB)
  418.                     rp->next->prev = rp->prev ;
  419.                 if (rp->prev != NULLNRRTAB)
  420.                     rp->prev->next = rp->next ;
  421.                 else
  422.                     Nrroute_tab[i] = rp->next ;
  423.  
  424.                 free(rp) ;
  425.             }
  426.         }
  427.     }
  428.  
  429.     start_timer(&Obsotimer) ;
  430. }
  431.  
  432.  
  433. static int donfadd(), donfdrop(), donfmode() ;
  434.  
  435. static struct cmds Nfcmds[] = {
  436.     "add",    donfadd,    0, 3,
  437.         "netrom nodefilter add <neighbor> <interface>",
  438.     "drop",    donfdrop,    0, 3,
  439.         "netrom nodefilter drop <neighbor> <interface>",
  440.     "mode",    donfmode,    0, 0,    NULLCHAR,
  441.     NULLCHAR,    NULLFP,    0, 0,
  442.         "nodefilter subcommands: add drop mode",
  443. } ;
  444.  
  445. /* nodefilter command multiplexer */
  446. static int
  447. donodefilter(argc,argv,envp)
  448. int argc ;
  449. char *argv[] ;
  450. void *envp;
  451. {
  452.     if (argc < 2) {
  453.         donfdump() ;
  454.         return 0 ;
  455.     }
  456.     return subcmd(Nfcmds,argc,argv,envp) ;
  457. }
  458.  
  459. /* display a list of <callsign,interface> pairs from the filter
  460.  * list.
  461.  */
  462. static int
  463. donfdump()
  464. {
  465.     int i, column = 1 ;
  466.     struct nrnf_tab *fp ;
  467.     char buf[16] ;
  468.  
  469.     for (i = 0 ; i < NRNUMCHAINS ; i++)
  470.         for (fp = Nrnf_tab[i] ; fp != NULLNRNFTAB ; fp = fp->next) {
  471.             pax25(buf,&fp->neighbor) ;
  472.             printf("%-7s %-8s  ",
  473.                     buf,Nrifaces[fp->iface].iface->name) ;
  474.             if (column++ == 4) {
  475.                 printf("\n") ;
  476.                 column = 1 ;
  477.             }
  478.         }
  479.  
  480.     if (column != 1)
  481.         printf("\n") ;
  482.  
  483.     return 0 ;
  484. }
  485.  
  486. /* add an entry to the filter table */
  487. static int
  488. donfadd(argc,argv)
  489. int argc ;
  490. char *argv[] ;
  491. {
  492.     struct ax25_addr neighbor ;
  493.     register int i ;
  494.  
  495.     /* format callsign */
  496.     if (setcall(&neighbor,argv[1]) == -1) {
  497.         printf("bad neighbor callsign\n") ;
  498.         return -1 ;
  499.     }
  500.  
  501.     /* find interface */
  502.     for (i = 0 ; i < Nr_numiface ; i++)
  503.         if (!strcmp(Nrifaces[i].iface->name,argv[2]))
  504.             break ;
  505.     if (i == Nr_numiface) {
  506.         printf("Interface \"%s\" not found\n",argv[2]) ;
  507.         return -1 ;
  508.     }
  509.  
  510.     return nr_nfadd(&neighbor,i) ;
  511. }
  512.  
  513. /* drop an entry from the filter table */
  514. static int
  515. donfdrop(argc,argv)
  516. int argc ;
  517. char *argv[] ;
  518. {
  519.     struct ax25_addr neighbor ;
  520.     register int i ;
  521.  
  522.     /* format neighbor callsign */
  523.     if (setcall(&neighbor,argv[1]) == -1) {
  524.         printf("bad neighbor callsign\n") ;
  525.         return -1 ;
  526.     }
  527.  
  528.     /* find interface */
  529.     for (i = 0 ; i < Nr_numiface ; i++)
  530.         if (!strcmp(Nrifaces[i].iface->name,argv[2]))
  531.             break ;
  532.     if (i == Nr_numiface) {
  533.         printf("Interface \"%s\" not found\n",argv[2]) ;
  534.         return -1 ;
  535.     }
  536.  
  537.     return nr_nfdrop(&neighbor,i) ;
  538. }
  539.  
  540. /* nodefilter mode subcommand */
  541. static int
  542. donfmode(argc,argv)
  543. int argc ;
  544. char *argv[] ;
  545. {
  546.     if (argc < 2) {
  547.         printf("filter mode is ") ;
  548.         switch (Nr_nfmode) {
  549.             case NRNF_NOFILTER:
  550.                 printf("none\n") ;
  551.                 break ;
  552.             case NRNF_ACCEPT:
  553.                 printf("accept\n") ;
  554.                 break ;
  555.             case NRNF_REJECT:
  556.                 printf("reject\n") ;
  557.                 break ;
  558.             default:
  559.                 printf("some strange, unknown value\n") ;
  560.         }
  561.         return 0 ;
  562.     }
  563.     
  564.     switch (argv[1][0]) {
  565.         case 'n':
  566.         case 'N':
  567.             Nr_nfmode = NRNF_NOFILTER ;
  568.             break ;
  569.         case 'a':
  570.         case 'A':
  571.             Nr_nfmode = NRNF_ACCEPT ;
  572.             break ;
  573.         case 'r':
  574.         case 'R':
  575.             Nr_nfmode = NRNF_REJECT ;
  576.             break ;
  577.         default:
  578.             printf("modes are: none accept reject\n") ;
  579.             return -1 ;
  580.     }
  581.  
  582.     return 0 ;
  583. }
  584.  
  585. /* verbose route broadcast */
  586. static int
  587. donrverbose(argc,argv)
  588. int argc ;
  589. char *argv[] ;
  590. {
  591.     if (argc < 2) {
  592.         printf("verbose is %s\n", Nr_verbose ? "yes" : "no" ) ;
  593.         return 0 ;
  594.     }
  595.     
  596.     switch (argv[1][0]) {
  597.         case 'n':
  598.         case 'N':
  599.             Nr_verbose = 0 ;
  600.             break ;
  601.         case 'y':
  602.         case 'Y':
  603.             Nr_verbose = 1 ;
  604.             break ;
  605.         default:
  606.             printf("use: netrom verbose [yes|no]\n") ;
  607.             return -1 ;
  608.     }
  609.  
  610.     return 0 ;
  611. }
  612.